import { PaymentRecord } from '../entities/PaymentRecord';
import { User } from '../entities/User';
import * as fs from 'fs';
import * as path from 'path';

/**
 * 支付凭证生成器
 * 用于生成支付凭证，包括SVG、JPG和文本格式
 */
export class PaymentProofGenerator {
  /**
   * 生成支付凭证
   * @param paymentRecord 支付记录
   * @param user 用户信息（可选）
   * @returns 支付凭证路径
   */
  public static async generatePaymentProof(paymentRecord: PaymentRecord, user?: User): Promise<string> {
    try {
      const qrcode = require('qrcode');
      const svg2img = require('svg2img');
      
      // 生成文本格式的支付凭证内容（但不保存为文件）
      const textContent = this.generateTextProofContent(paymentRecord, user);
      console.log(`已生成文本凭证内容`);
      
      // 确保金额是数字类型
      const amount = typeof paymentRecord.amount === 'string' 
        ? parseFloat(paymentRecord.amount) 
        : paymentRecord.amount;
      
      try {
        // 生成二维码
        let qrCodeDataUrl = '';
        try {
          // 创建包含支付信息的JSON对象
          const qrData = {
            orderNo: paymentRecord.orderNo,
            amount: amount.toFixed(2),
            transactionId: paymentRecord.transactionId || '',
            paymentTime: paymentRecord.paymentTime?.toISOString() || '',
            status: paymentRecord.status
          };
          
          // 生成二维码图片
          qrCodeDataUrl = await qrcode.toDataURL(JSON.stringify(qrData), {
            errorCorrectionLevel: 'H',
            margin: 1,
            width: 150
          });
        } catch (qrError) {
          console.error('生成二维码失败:', qrError);
          qrCodeDataUrl = '';
        }
        
        // 创建SVG内容
        const svgContent = `
        <svg width="600" height="800" xmlns="http://www.w3.org/2000/svg">
          <rect width="600" height="800" fill="white"/>
          
          <!-- 标题 -->
          <text x="300" y="50" font-size="32" font-weight="bold" text-anchor="middle" fill="black">支付凭证</text>
          
          <!-- 分割线 -->
          <line x1="50" y1="80" x2="550" y2="80" stroke="#AAAAAA" stroke-width="1"/>
          
          <!-- 订单信息 -->
          <text x="50" y="130" font-size="18" fill="black">订单编号: ${paymentRecord.orderNo}</text>
          <text x="50" y="160" font-size="18" fill="black">支付项目: ${paymentRecord.description || paymentRecord.paymentItem}</text>
          <text x="50" y="190" font-size="18" fill="black">支付金额: ${amount.toFixed(2)} 元</text>
          <text x="50" y="220" font-size="18" fill="black">支付方式: ${paymentRecord.paymentMethodText}</text>
          <text x="50" y="250" font-size="18" fill="black">交易号: ${paymentRecord.transactionId || '无'}</text>
          <text x="50" y="280" font-size="18" fill="black">支付时间: ${paymentRecord.paymentTime?.toLocaleString() || '无'}</text>
          <text x="50" y="310" font-size="18" fill="black">支付状态: ${paymentRecord.statusText}</text>
          
          <!-- 分割线 -->
          <line x1="50" y1="340" x2="550" y2="340" stroke="#AAAAAA" stroke-width="1"/>
          
          <!-- 用户信息 -->
          <text x="50" y="370" font-size="18" fill="black">用户姓名: ${user?.name || '未设置'}</text>
          <text x="50" y="400" font-size="18" fill="black">用户手机: ${user?.mobile || '未设置'}</text>
          
          ${qrCodeDataUrl ? `
          <!-- 二维码 -->
          <image x="225" y="450" width="150" height="150" href="${qrCodeDataUrl}"/>
          <text x="300" y="630" font-size="14" text-anchor="middle" fill="black">扫描二维码验证支付信息</text>
          ` : ''}
          
          <!-- 底部信息 -->
          <text x="300" y="680" font-size="14" text-anchor="middle" fill="black">本凭证由系统自动生成，感谢您的支付！</text>
          <text x="300" y="710" font-size="14" text-anchor="middle" fill="black">生成时间: ${new Date().toLocaleString()}</text>
        </svg>
        `;
        
        // 准备文件目录
        const appConfig = require('../config/app').default;
        const today = new Date().toISOString().split('T')[0];
        let uploadDir = `${appConfig.uploadPath}/${today}/payment_proof`;
        
        if (uploadDir.startsWith('../')) {
          uploadDir = uploadDir.replace('../', '');
        }
        
        if (!fs.existsSync(uploadDir)) {
          fs.mkdirSync(uploadDir, { recursive: true });
          console.log(`创建支付凭证目录: ${uploadDir}`);
        }
        
        // 保存SVG文件（临时）
        const svgFilename = `payment_proof_${paymentRecord.orderNo}.svg`;
        const svgFilepath = path.join(uploadDir, svgFilename);
        fs.writeFileSync(svgFilepath, svgContent, 'utf8');
        console.log(`支付凭证SVG已生成: ${svgFilepath}`);
        
        // 将SVG转换为JPG
        const jpgFilename = `payment_proof_${paymentRecord.orderNo}.jpg`;
        const jpgFilepath = path.join(uploadDir, jpgFilename);
        
        // 使用svg2img转换SVG为JPG
        await new Promise<void>((resolve, reject) => {
          svg2img(svgContent, { format: 'jpg', quality: 90 }, (error: Error, buffer: Buffer) => {
            if (error) {
              console.error('转换SVG到JPG失败:', error);
              reject(error);
              return;
            }
            
            fs.writeFileSync(jpgFilepath, buffer);
            console.log(`支付凭证JPG已生成: ${jpgFilepath}`);
            resolve();
          });
        });
        
        // 删除中间SVG文件
        try {
          fs.unlinkSync(svgFilepath);
          console.log(`已删除中间SVG文件: ${svgFilepath}`);
        } catch (deleteError) {
          console.warn(`删除中间SVG文件失败: ${svgFilepath}`, deleteError);
          // 继续执行，不影响主流程
        }
        
        // 返回JPG图片的相对路径
        return `/uploads/${today}/payment_proof/${jpgFilename}`;
      } catch (svgError) {
        console.error('生成SVG凭证失败:', svgError);
        
        // 如果SVG生成失败，尝试使用canvas直接生成图片
        try {
          const { createCanvas } = require('canvas');
          
          // 创建一个简单的英文版本的凭证
          const canvas = createCanvas(600, 800);
          const ctx = canvas.getContext('2d');
          
          // 设置白色背景
          ctx.fillStyle = '#FFFFFF';
          ctx.fillRect(0, 0, 600, 800);
          
          // 设置字体和颜色
          ctx.fillStyle = '#000000';
          
          // 添加标题（使用英文）
          ctx.font = 'bold 32px Arial';
          ctx.textAlign = 'center';
          ctx.fillText('Payment Receipt', 300, 50);
          
          // 添加分割线
          ctx.strokeStyle = '#AAAAAA';
          ctx.beginPath();
          ctx.moveTo(50, 80);
          ctx.lineTo(550, 80);
          ctx.stroke();
          
          // 设置常规文本字体
          ctx.font = '18px Arial';
          ctx.textAlign = 'left';
          
          // 添加订单信息（使用英文）
          ctx.fillText(`Order No: ${paymentRecord.orderNo}`, 50, 130);
          ctx.fillText(`Amount: ${amount.toFixed(2)} CNY`, 50, 160);
          ctx.fillText(`Method: ${paymentRecord.paymentMethod}`, 50, 190);
          ctx.fillText(`Transaction ID: ${paymentRecord.transactionId || 'N/A'}`, 50, 220);
          ctx.fillText(`Payment Time: ${paymentRecord.paymentTime?.toLocaleString() || 'N/A'}`, 50, 250);
          
          // 添加底部信息
          ctx.font = '14px Arial';
          ctx.textAlign = 'center';
          ctx.fillText('For detailed receipt in Chinese, please check the text file.', 300, 680);
          
          const appConfig = require('../config/app').default;
          const today = new Date().toISOString().split('T')[0];
          let uploadDir = `${appConfig.uploadPath}/${today}/payment_proof`;
          
          if (uploadDir.startsWith('../')) {
            uploadDir = uploadDir.replace('../', '');
          }
          
          if (!fs.existsSync(uploadDir)) {
            fs.mkdirSync(uploadDir, { recursive: true });
            console.log(`创建支付凭证目录: ${uploadDir}`);
          }
          
          const jpgFilename = `payment_proof_${paymentRecord.orderNo}.jpg`;
          const jpgFilepath = path.join(uploadDir, jpgFilename);
          
          // 将canvas保存为图片文件
          const buffer = canvas.toBuffer('image/jpeg', { quality: 0.95 });
          fs.writeFileSync(jpgFilepath, buffer);
          console.log(`备用支付凭证图片已生成: ${jpgFilepath}`);
          
          // 返回JPG图片的相对路径
          return `/uploads/${today}/payment_proof/${jpgFilename}`;
        } catch (canvasError) {
          console.error('使用Canvas生成凭证失败:', canvasError);
          // 如果所有尝试都失败，保存并返回文本凭证路径
          const textProofPath = this.saveTextProof(paymentRecord, user, textContent);
          return textProofPath;
        }
      }
    } catch (error: any) {
      console.error('生成支付凭证失败:', error);
      throw error;
    }
  }
  
  /**
   * 生成文本格式的支付凭证内容（不保存文件）
   * @param paymentRecord 支付记录
   * @param user 用户信息
   * @returns 文本内容
   */
  private static generateTextProofContent(paymentRecord: PaymentRecord, user?: User): string {
    // 确保金额是数字类型
    const amount = typeof paymentRecord.amount === 'string' 
      ? parseFloat(paymentRecord.amount) 
      : paymentRecord.amount;
    
    // 生成文本格式的支付凭证
    return [
      '====================================',
      '               支付凭证              ',
      '====================================',
      '',
      `订单编号: ${paymentRecord.orderNo}`,
      `支付项目: ${paymentRecord.description || paymentRecord.paymentItem}`,
      `支付金额: ${amount.toFixed(2)} 元`,
      `支付方式: ${paymentRecord.paymentMethodText}`,
      `交易号: ${paymentRecord.transactionId || '无'}`,
      `支付时间: ${paymentRecord.paymentTime?.toLocaleString() || '无'}`,
      `支付状态: ${paymentRecord.statusText}`,
      '',
      '------------------------------------',
      '',
      `用户姓名: ${user?.name || '未设置'}`,
      `用户手机: ${user?.mobile || '未设置'}`,
      '',
      '------------------------------------',
      '',
      '本凭证由系统自动生成，感谢您的支付！',
      `生成时间: ${new Date().toLocaleString()}`,
      '',
      '===================================='
    ].join('\n');
  }
  
  /**
   * 保存文本格式的支付凭证（仅在图片生成失败时调用）
   * @param paymentRecord 支付记录
   * @param user 用户信息
   * @param textContent 文本内容
   * @returns 文本文件路径
   */
  private static saveTextProof(paymentRecord: PaymentRecord, user?: User, textContent?: string): string {
    try {
      // 如果没有提供文本内容，则重新生成
      const content = textContent || this.generateTextProofContent(paymentRecord, user);
      
      // 保存文本文件
      const appConfig = require('../config/app').default;
      const today = new Date().toISOString().split('T')[0];
      let uploadDir = `${appConfig.uploadPath}/${today}/payment_proof`;
      
      if (uploadDir.startsWith('../')) {
        uploadDir = uploadDir.replace('../', '');
      }
      
      if (!fs.existsSync(uploadDir)) {
        fs.mkdirSync(uploadDir, { recursive: true });
        console.log(`创建支付凭证目录: ${uploadDir}`);
      }
      
      // 保存文本文件
      const textFilename = `payment_proof_${paymentRecord.orderNo}.txt`;
      const textFilepath = path.join(uploadDir, textFilename);
      fs.writeFileSync(textFilepath, content, 'utf8');
      console.log(`支付凭证文本文件已生成: ${textFilepath}`);
      
      // 返回相对路径
      return `/uploads/${today}/payment_proof/${textFilename}`;
    } catch (textError) {
      console.error('生成文本凭证失败:', textError);
      return '';
    }
  }
} 